﻿using DFGK_WMS.IRepository;
using DFGK_WMS.IRepository.蒙牛;
using DFGK_WMS.Model.DTO;
using DFGK_WMS.Model.Models;
using DFGK_WMS.WebAPI.AttributeFile;
using DFGK_WMS.WebAPI.Controllers.Result;
using DFGK_WMS.WebAPI.Filter;
using DFGK_WMS.WebAPI.Tools;
using Microsoft.AspNetCore.Mvc;
using System.Net.Mime;
using System.Security.Claims;

namespace DFGK_WMS.WebAPI.Controllers.收货管理.蒙牛收获管理
{
    /// <summary>
    /// 收货管理(蒙牛)
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class TMNReceivingBillController : ControllerBase
    {
        private readonly ITDictItemRepository tDictItemRepository;
        private readonly ITDictTypeRepository tDictType;
        private readonly ILogRepository logRepository;

        public IMNTReceivingBillRepository TreceService { get; }

        public TMNReceivingBillController(IMNTReceivingBillRepository treceService, ITDictItemRepository tDictItemRepository,ITDictTypeRepository tDictType,ILogRepository logRepository)
        {
            TreceService = treceService;
            this.tDictItemRepository = tDictItemRepository;
            this.tDictType = tDictType;
            this.logRepository = logRepository;
        }


        /// <summary>
        /// 显示收货管理
        /// </summary>
        /// <param name="startTime">开始时间</param>
        /// <param name="endTime">结束时间</param>
        /// <param name="status"></param>
        /// <param name="customerId"></param>
        /// <param name="warehouseId"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetReceivingBillList(DateTime? startTime, DateTime? endTime, int? customerId,int? status = 4, int? warehouseId = 0, int pageIndex = 1, int pageSize = 10)
        {
            if (pageIndex <= 0 || pageSize <= 0)
            {
                return Ok(BaseResult.Result("400", "分页条件有误！"));
            }
            int totalCount;

            var list = TreceService.GetReceivingBillList(startTime,endTime, customerId, status, warehouseId.GetValueOrDefault(), pageIndex, pageSize, out totalCount);

            if (list != null)
            {
                return Ok(BaseResult.Result(list, "查询成功！", "200", totalCount));
            }
            return Ok(BaseResult.Result(null, "查询失败！", "500", 0));
        }
        /// <summary>
        /// 导出
        /// </summary>
        /// <param name="createDate"></param>
        /// <param name="customerId"></param>
        /// <param name="status"></param>
        /// <param name="warehouseId"></param>
        /// <returns></returns>
        [HttpGet]
        public FileContentResult ExportToExcel(DateTime? startTime, DateTime? endTime, int? customerId, int? status = 4, int? warehouseId = 0)
        {
            var list = TreceService.GetReceivingBillList(startTime,endTime, customerId, status, warehouseId.GetValueOrDefault(), 1, int.MaxValue, out var totalCount);
            Dictionary<string, string> keyValuePairs = new Dictionary<string, string>()
            {
                {"BillNo","单号" },
                {"CustomerName","客户名称" },
                {"TotalQty","总数量" },
                {"ReceivedQTY","已收货数量" },
                {"exStatus","状态" },
                {"Receiver","收货人" },
                {"StoLocation","库存地点" },
                {"BeginDate","开始时间" },
                {"EndDate","完成时间" },
                {"CreateDate","创建时间" },
            };
            //直接匿名对象就好
            var exList = list.Select(s => new 
            {   s.BillNo,
                s.CreateDate, 
                s.CustomerName,
                TotalQty=(int)s.TotalQty.GetValueOrDefault(),
                ReceivedQTY=(int)s.ReceivedQTY.GetValueOrDefault(),
                s.Receiver,
                s.BeginDate,
                s.StoLocation,
                s.EndDate,
                exStatus = ExStatusMapper(s.Status)
            }).ToList();
            
            var fileBytes = Utils.ExportToExcel(exList, keyValuePairs);
            return File(fileBytes, MediaTypeNames.Application.Octet, "收货管理.xlsx");
        }
        //状态转换
        private string ExStatusMapper(int status)
        {
            if (status == 0)
            {
                return "未开始";
            }
            if (status == 1)
            {
                return "未完成";
            }
            if (status == 2)
            {
                return "已完成";
            }
            return "";
        }
        /// <summary>
        /// 收货管理的导出DTO
        /// </summary>
        /// <param name="billNo"></param>
        /// <param name="createDate"></param>
        /// <param name="customerName"></param>
        public record DaoChuDTO(string billNo,DateTime createDate,string customerName);

        /// <summary>
        /// 添加收货单
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        [HttpPost]
        [HttpIdempotent(WaitMillisecond = 10000, CacheMillisecond = 3000)]
        public IActionResult AddReceivingBill(TReceivingBill m)
        {
            if (string.IsNullOrEmpty(m.BillNo))
            {
                return Ok(BaseResult.Result("400", "单号不能为空！"));
            }
            string message = "";
            bool IsOK = TreceService.AddReceivingBill(m, out message);
            if (IsOK)
            {
                string uname = HttpContext.User.FindFirstValue("UserName");
                string runame = HttpContext.User.FindFirstValue("RealName");
                int uid = Convert.ToInt32(HttpContext.User.FindFirstValue("Id"));
                string? ip = HttpContext.Connection.RemoteIpAddress?.ToString();
                TLog logg = new TLog();
                logg.LogType = 1;
                logg.ActionType = 4;
                logg.ModuleName = "收货管理";
                logg.UserName = uname;
                logg.RealName = runame;
                logg.UserId = uid;
                logg.Description = uname + "创建了收货单" + m.BillNo;
                //获取前端IP地址
                logg.Ipaddress = ip;

                logRepository.AddTLod(logg);
                return Ok(BaseResult.Result(true, "添加成功！", "200"));
            }
            return Ok(BaseResult.Result(false, "添加失败！" + message, "500"));
        }

        /// <summary>
        /// 删除收货单
        /// </summary>
        /// <param name="rid"></param>
        /// <returns></returns>
        [HttpDelete]
        public IActionResult DelReceivingBill(int rid)
        {
            if (rid <= 0)
            {
                return Ok(BaseResult.Result("400", "Id有误！"));
            }
            bool IsOK = TreceService.DelReceivingBill(rid, out string message);
            string uname = HttpContext.User.FindFirstValue("UserName");
            string runame = HttpContext.User.FindFirstValue("RealName");
            int uid = Convert.ToInt32(HttpContext.User.FindFirstValue("Id"));
            string? ip = HttpContext.Connection.RemoteIpAddress?.ToString();
            TLog logg = new TLog();
            logg.LogType = 1;
            logg.ActionType = 4;
            logg.ModuleName = "删除收货单";
            logg.UserName = uname;
            logg.RealName = runame;
            logg.UserId = uid;
            logg.Description = IsOK ? uname + "删除了收货单" : uname + "删除收货单失败: " + message;
            logg.Ipaddress = ip;
            logRepository.AddTLod(logg);
            if (IsOK)
            {
                return Ok(BaseResult.Result(true, "删除成功！", "200"));
            }
            return Ok(BaseResult.Result(false, "收货中或已完成的收货单不允许删除！", "500"));
        }
        /// <summary>
        /// 批量删除收货单
        /// </summary>
        /// <param name="ridList"></param>
        /// <returns></returns>
        [HttpDelete]
        public IActionResult DelsReceivingBills(int[] ridList)
        {
            if (ridList.Length <= 0)
            {
                return Ok(BaseResult.Result("400", "Id有误！"));
            }
            var IsOK = TreceService.DelsReceivingBills(ridList, out string message);
            if (IsOK)
            {
                return Ok(BaseResult.Result(true, "删除成功！", "200"));
            }
            return Ok(BaseResult.Result(false, "收获单删除失败！"+ message, "500"));
        }

        /// <summary>
        /// 根据Id获取对象
        /// </summary>
        /// <param name="rid"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetTReceivingBillById(int rid)
        {
            if (rid <= 0)
            {
                return Ok(BaseResult.Result("400", "Id有误！"));
            }
            var mobj = TreceService.GetTReceivingBillById(rid);
            if (mobj != null)
            {
                return Ok(BaseResult.Result(mobj, "获取成功", "200"));
            }
            return Ok(BaseResult.Result(null, "获取失败！", "500"));
        }

        /// <summary>
        /// 修改收货单
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        [HttpPut]
        public IActionResult UpdReceivingBill(TReceivingBill m)
        {
            if (m.Id <= 0)
            {
                return Ok(BaseResult.Result("400", "Id有误！"));
            }
            if (string.IsNullOrEmpty(m.BillNo))
            {
                return Ok(BaseResult.Result("400", "单号不能为空！"));
            }
            string message = "";
            bool IsOK = TreceService.UpdReceivingBill(m, out message);
            if (IsOK)
            {
                string uname = HttpContext.User.FindFirstValue("UserName");
                string runame = HttpContext.User.FindFirstValue("RealName");
                int uid = Convert.ToInt32(HttpContext.User.FindFirstValue("Id"));
                string? ip = HttpContext.Connection.RemoteIpAddress?.ToString();
                TLog logg = new TLog();
                logg.LogType = 1;
                logg.ActionType = 6;
                logg.ModuleName = "收货管理";
                logg.UserName = uname;
                logg.RealName = runame;
                logg.UserId = uid;
                logg.Description = uname + "修改了收货单" + m.BillNo;
                //获取前端IP地址
                logg.Ipaddress = ip;

                logRepository.AddTLod(logg);
                return Ok(BaseResult.Result(true, "修改成功！", "200"));
            }
            return Ok(BaseResult.Result(false, "修改失败！" + message, "500"));
        }

        /// <summary>
        /// 根据物料分类id返回物料
        /// </summary>
        /// <param name="mid"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetRidById(int mid)
        {
            if (mid <= 0)
            {
                return Ok(BaseResult.Result("400", "Id有误！"));
            }
            var mobj = TreceService.GetRidById(mid);
            if (mobj != null)
            {
                return Ok(BaseResult.Result(mobj, "获取成功", "200"));
            }
            return Ok(BaseResult.Result(null, "获取失败！", "500"));
        }

        /// <summary>
        /// 收货入库（PC）
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [TypeFilter(typeof(LogActionFilter))]
        [HttpIdempotent(WaitMillisecond = 10000, CacheMillisecond = 3000)]
        public IActionResult BuildCreateStackingStorage(ReceivingBillOrderDto m)
        {
            if (m.Id <= 0)
            {
                return Ok(BaseResult.Result("400", "Id有误！"));
            }
            m.NowUserId = Convert.ToInt32(HttpContext.User.FindFirstValue("Id"));
            m.NowUserRealName = HttpContext.User.FindFirstValue("UserName");
            string message = "";
            List<TCell> Getcell = new List<TCell>();
            bool IsOK = TreceService.AddPDAReceivingOrderDateil(m, out message, ref Getcell);
            string uname = HttpContext.User.FindFirstValue("UserName");
            string runame = HttpContext.User.FindFirstValue("RealName");
            int uid = Convert.ToInt32(HttpContext.User.FindFirstValue("Id"));
            m.NowUserRealName = uname;//创建人
            m.NowUserId = uid;//创建人id
            string? ip = HttpContext.Connection.RemoteIpAddress?.ToString();
            TLog logg = new TLog();
            logg.LogType = 1;
            logg.ActionType = 4;
            logg.ModuleName = "添加组垛";
            logg.UserName = uname;
            logg.RealName = runame;
            logg.UserId = uid;
            logg.Description = IsOK ? uname + "创建了组垛" : uname + "创建组垛失败: " + message;
            logg.Ipaddress = ip;
            logRepository.AddTLod(logg);
            if (IsOK)
            {
                var iscell = "";
                foreach (var item in Getcell)
                {
                    iscell += item.Name;
                }
                return Ok(BaseResult.Result(true, "入库成功！分配的仓位为：" + iscell, "200"));
            }
            return Ok(BaseResult.Result(false, message, "500"));
        }
        /// <summary>
        /// 获取小批次号
        /// </summary>
        /// <param name="BatchNo"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetSmallBatchNo(string BatchNo)
        {
            if (BatchNo is null || BatchNo == "")
            {
                return Ok(BaseResult.Result("500", "参数有误！"));
            }
            string res = "";
            var data = BatchNo.ToArray();
            if (GetMM(data[4]) == "")
            {
                return Ok(BaseResult.Result("500", "没有查出相对应的月份！"));
            }
            res = res + data[0].ToString();
            res = res + "20" + data[2].ToString() + data[3].ToString();
            res = res + GetMM(data[4]);
            res = res + data[5].ToString() + data[6].ToString();
            res = res + data[1].ToString();
            res = res + data[7].ToString() + data[8].ToString() + data[9].ToString();
            return Ok(BaseResult.Result(res, "成功生成小批次号！", "200"));

        }
        private string GetMM(char zm)
        {
            switch (zm)
            {
                case 'A':
                    return "00";
                case 'B':
                    return "01";
                case 'C':
                    return "02";
                case 'D':
                    return "03";
                case 'E':
                    return "04";
                case 'F':
                    return "05";
                case 'G':
                    return "06";
                case 'H':
                    return "07";
                case 'J':
                    return "08";
                case 'K':
                    return "09";
                case 'L':
                    return "10";
                case 'M':
                    return "11";
                case 'N':
                    return "12";
                case 'O':
                    return "13";
                case 'P':
                    return "14";
                case 'Q':
                    return "15";
                case 'R':
                    return "16";
                case 'S':
                    return "17";
                case 'T':
                    return "18";
                case 'U':
                    return "19";
                case 'V':
                    return "20";
                case 'W':
                    return "21";
                case 'X':
                    return "22";
                case 'Y':
                    return "23";
                case 'Z':
                    return "24";
                default:
                    return "";
            }
        }

        /// <summary>
        /// 强制完成
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult ForceFinished(int id)
        {
            if (id <= 0)
            {
                return Ok(BaseResult.Result(false, "Id不正确！", "500"));
            }
            var receivingBill = TreceService.GetTReceivingBillById(id);
            if (receivingBill is null)
            {
                return Ok(BaseResult.Result(false, "参数错误！", "500"));
            }
            else
            {
                if (receivingBill.Status == 2)
                {
                    return Ok(BaseResult.Result(true, "此收货单已完成，请勿重复操作！", "200"));
                }
            }
            var isok = TreceService.ReceivingBillComplete(id);
            if (isok)
            {
                return Ok(BaseResult.Result(true, "强制完成,成功！", "200"));
            }
            return Ok(BaseResult.Result(false, "强制完成,失败！！", "200"));

        }
        /// <summary>
        /// 修改状态
        /// </summary>
        /// <param name="rid"></param>
        /// <returns></returns>
        [HttpPut]
        public IActionResult UpdReceivingBillStatus(int rid)
        {
            if (rid <= 0)
            {
                return Ok(BaseResult.Result("400", "Id有误！"));
            }
            bool IsOK = TreceService.UpdReceivingBillStatus(rid);
            if (IsOK)
            {
                return Ok(BaseResult.Result(true, "保存成功！", "200"));
            }
            return Ok(BaseResult.Result(false, "保存失败！", "500"));
        }

        /// <summary>
        /// 获取收获单据类型
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetDictReceiving()
        {
            var tyepName = tDictType.GetAll().FirstOrDefault(s => s.TypeName == "收货单据类型");
            if (tyepName == null)
            {
                return Ok(BaseResult.Result("500", "找不到收货单据类型"));
            }
            var dicItem = tDictItemRepository.GetDictItems().Where(s => s.TypeId == tyepName.Id);
            if (dicItem != null && dicItem.Any())
            {
                return Ok(BaseResult.Result(dicItem, "200"));
            }
            return Ok(BaseResult.Result("500", "系统错误，找不到收货单据类型"));
        }


        /// <summary>
        /// 根据托盘条码带出满载率
        /// </summary>
        /// <param name="PallerBarcode"></param>
        /// <returns></returns>
        [HttpGet]
        public IActionResult GetLoadFactorByPallBarcode(string PallerBarcode)
        {

            var dicItem = TreceService.GetLoadFactorByPallBarcode(PallerBarcode);
            if (dicItem != 0)
            {
                return Ok(BaseResult.Result(dicItem ,"满载率为"+ dicItem + "%" ,"200"));
            }
            return Ok(BaseResult.Result(dicItem, "满载率为" + 0 + "%", "200"));
        }
    }
}
